package sw6.digipecs.widget;

import java.util.Random;

import sw6.digipecs.R;
import sw6.digipecs.database.DBAdapter;
import sw6.digipecs.exceptions.DatabaseException;
import sw6.digipecs.exceptions.ImageIsEmptyException;
import sw6.digipecs.exceptions.SoundNotFoundException;
import sw6.digipecs.helpers.AudioPlayer;
import sw6.digipecs.helpers.SoundRecorder;
import sw6.digipecs.helpers.ToastHelper;
import sw6.digipecs.interfaces.ImageModificationListener;
import sw6.digipecs.model.ExtImage;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * @author sw6a This class defines a compound view for modifying extended
 *         pictures. This view is used when modifying existing images in the
 *         pecs book and to modify images taken with the camera. a newly added
 *         image
 */
public class ImageModifierView extends LinearLayout {
	public static final int IMAGE_MODE_ADD = 1;
	public static final int IMAGE_MODE_MODIFY = 2;

	private static final String LOG_TAG = "sw6.digipecs.admin";
	private Context mContext;
	private Activity mActivity;
	private ExtImage mSelectedPicture;
	private boolean mIsRecording;
	private String mTempSoundPath;
	private int mImageMode = 2;
	private ImageModificationListener mModificationListener = null;
	private SoundRecorder mSoundRecorder;
	private Bitmap mTempBitmap = null;

	private ImageView mImagePreview;
	private EditText mModifyPictureTextBox;
	private Button mSaveModificationButton;
	private Button mDeletePictureButton;
	private ImageButton mPlaySoundButton;
	private ImageButton mRecordSoundButton;
	private TextView mSaveImageText;

	/**
	 * Standard view constructor
	 * 
	 * @param context
	 */
	public ImageModifierView(Context context) {
		super(context);
		this.mContext = context;
		initialise();
	}

	/**
	 * standard view constructor
	 * 
	 * @param context
	 * @param atts
	 */
	public ImageModifierView(Context context, AttributeSet atts) {
		super(context, atts);
		mContext = context;
		initialise();
	}

	private void initialise() {
		String infService = Context.LAYOUT_INFLATER_SERVICE;
		LayoutInflater li;
		li = (LayoutInflater) getContext().getSystemService(infService);
		li.inflate(R.layout.imagemodifierviewlayout, this, true);
		mImagePreview = (ImageView) findViewById(R.id.modifypicturepreview);
		mModifyPictureTextBox = (EditText) findViewById(R.id.modifipictureedittext);
		mSaveModificationButton = (Button) findViewById(R.id.modifipicturesavebutton);
		mSaveModificationButton.setOnClickListener(clickHandler);
		mDeletePictureButton = (Button) findViewById(R.id.modifipicturedeletebutton);
		mDeletePictureButton.setOnClickListener(clickHandler);
		mPlaySoundButton = (ImageButton) findViewById(R.id.modifiPictureSoundPlayButton);
		mPlaySoundButton.setOnClickListener(clickHandler);
		mPlaySoundButton.setEnabled(false);
		mRecordSoundButton = (ImageButton) findViewById(R.id.modifiPictureSoundRecordButton);
		mRecordSoundButton.setOnClickListener(clickHandler);
		mSaveImageText = (TextView) findViewById(R.id.saveModifiedImageText);
		mSelectedPicture = null;
	}

	/**
	 * This private object handles all buttonclicks.
	 */
	private OnClickListener clickHandler = new OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.modifipicturesavebutton:
				savePicture();
				break;
			case R.id.modifiPictureSoundRecordButton:
				log("record button pressed");
				handleRecordPress();
				break;
			case R.id.modifipicturedeletebutton:
				deletePicture();
				break;
			case R.id.modifiPictureSoundPlayButton:
				playSound();
				break;
			}
		}
	};

	private void playSound() {
		String source = null;
		if (mTempSoundPath != null) {
			source = mTempSoundPath;
			log("mediaplayer source is Temps");
		} else if (mSelectedPicture.hasSound()) {
			try {
				source = mSelectedPicture.getSound();
				log("Mediaplayer source is file");
			} catch (ImageIsEmptyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SoundNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (source != null) {
			mPlaySoundButton.setEnabled(false);
			AudioPlayer.open();
			AudioPlayer.play(source, new OnCompletionListener() {
				@Override
				public void onCompletion(MediaPlayer mp) {
					mPlaySoundButton.setEnabled(true);
					AudioPlayer.close();
				}
			});

			log("playing sound");
		}
	}

	private void savePicture() {
		if (mImageMode == IMAGE_MODE_MODIFY) {
			try {
				mSelectedPicture.setText(mModifyPictureTextBox.getText()
						.toString());
			} catch (ImageIsEmptyException e) {
				e.printStackTrace();
			}

			if (mTempSoundPath != null) {
				try {
					mSelectedPicture.setSound(mTempSoundPath);
					mTempSoundPath = null;
				} catch (ImageIsEmptyException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if(sw6.lib.Settings.getBoolean(mContext, "helptext"))
					ToastHelper.makeText(mContext, mContext.getString(R.string.helpModificationsSaved)); 
			}
		} else if (mImageMode == IMAGE_MODE_ADD) {
			String uriPath = saveImageAndGetPath();
			String soundPath = mTempSoundPath;

			try {
				ExtImage.CreateNew(mContext, uriPath,
						(mModifyPictureTextBox.getText()).toString(), soundPath);
			} catch (DatabaseException e) {
			}
			if(sw6.lib.Settings.getBoolean(mContext, "helptext"))
				ToastHelper.makeText(mContext, mContext.getString(R.string.helpImageAdded)); 
		}

		if (mModificationListener != null)
			mModificationListener.ImageSaved();
	}

	private String saveImageAndGetPath() {
		String url = Images.Media.insertImage(mContext.getContentResolver(),
				mTempBitmap, null, null);
		mTempBitmap.recycle();

		if (url != null) {
			String realPath = getRealPathFromURI(Uri.parse(url));
			return realPath;
		}
		return null;
	}

	private void deletePicture() {
		//TODO KENNETH: This is a violation of architecture !!!
		DBAdapter adapter = new DBAdapter(mContext);
		adapter.open();
		try {
			adapter.deletePicture(mSelectedPicture.getId());
		} catch (ImageIsEmptyException e) {
			e.printStackTrace();
		}
		adapter.close();
		if (mModificationListener != null)
			mModificationListener.ImageDeleted();
	}

	private void handleRecordPress() {
		if (!mIsRecording) {
			mIsRecording = true;
			mSoundRecorder = SoundRecorder.getinstance(mContext);
			try {
				if (mImageMode == IMAGE_MODE_MODIFY)
					mSoundRecorder.startRecording(mSelectedPicture.getId());
				if (mImageMode == IMAGE_MODE_ADD) {
					Random random = new Random(System.currentTimeMillis());
					int number = random.nextInt();
					mSoundRecorder.startRecording(number);
				}

				mPlaySoundButton.setEnabled(false);
				mRecordSoundButton.setImageResource(R.drawable.stop);
			} catch (ImageIsEmptyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			mIsRecording = false;
			mTempSoundPath = mSoundRecorder.stopRecording();
			mPlaySoundButton.setEnabled(true);
			mRecordSoundButton.setImageResource(R.drawable.record);
		}
	}

	public void setSelectedImage(ExtImage selectedImage) {
		mSelectedPicture = selectedImage;
		try {
			mModifyPictureTextBox.setText(mSelectedPicture.getText());
			mImagePreview.setImageURI(Uri.parse(mSelectedPicture.getUri()));
			if (mSelectedPicture.hasSound())
				mPlaySoundButton.setEnabled(true);
			else
				mPlaySoundButton.setEnabled(false);
		} catch (ImageIsEmptyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		mTempSoundPath = null;
	}

	public ExtImage getSelectedImage() {
		return mSelectedPicture;
	}

	private void log(String string) {
		Log.i(LOG_TAG, string);
	}

	public void setImageModificationListener(ImageModificationListener listener) {
		this.mModificationListener = listener;
	}

	public void setImageMode(int imageMode) {
		if (imageMode == IMAGE_MODE_ADD) {
			log("image mode add");
			mDeletePictureButton.setVisibility(View.INVISIBLE);
			mSaveImageText.setText(mContext
					.getString(R.string.addPictureSaveDescription));
			mSaveModificationButton.setText(mContext
					.getString(R.string.addPictureSaveButtonText));
			mSaveModificationButton.setEnabled(false);
		}
		if (imageMode == IMAGE_MODE_MODIFY) {
			log("image mode modify");
			mDeletePictureButton.setVisibility(View.VISIBLE);
			mSaveImageText.setText(mContext
					.getString(R.string.modifyPictureSaveDescription));
			mSaveModificationButton.setText(mContext
					.getString(R.string.modifyPictureSaveButtonText));
		}
		mImageMode = imageMode;
	}

	public void setPreviewImage(Bitmap image) {
		if (image != null) {
			mImagePreview.setImageBitmap(image);
			mTempBitmap = image;
			mSaveModificationButton.setEnabled(true);
		}
	}

	public void setActivity(Activity activity) {
		mActivity = activity;
	}

	public String getRealPathFromURI(Uri contentUri) {
		String[] proj = { MediaStore.Images.Media._ID };
		Cursor cursor = mActivity.managedQuery(contentUri, proj, null, null,
				null);
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
		cursor.moveToFirst();
		final int id = cursor.getInt(column_index);

		String[] proj2 = { MediaStore.Images.Thumbnails.DATA };
		cursor = mActivity.managedQuery(
				MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, proj2,
				MediaStore.Images.Thumbnails.IMAGE_ID + " = " + id, null, null);
		cursor.moveToFirst();
		column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA);
		final String uri = cursor.getString(column_index);

		return uri;
	}
}
